﻿using DataWorks_Tools.BasicMethods;
using DataWorks_Tools.MappModals;
using DataWorks_Tools.MergeDetails;
using DataWorks_Tools.ProcessExcute.ProcessReporter;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DataWorks_Tools.CleanDetails
{
    public static class CleanDetailsMethods
    {
        /// <summary>
        /// 判断csv数据有没有满2561行或者是否有空的列
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool YXHJudgeNullinCSV(string[] list)
        {
            bool result = false;
            if (list.Length != 2561)
            {
                return true;
            }
            else
            {
                list[0] = list[0].Replace(" ", "");
                foreach (var item in list)
                {
                    //var l = item.Split(",");
                    var n = item.Split(",").Any(a => string.IsNullOrWhiteSpace(a));
                    if (n)
                    {
                        //Console.WriteLine(item);
                        result = true;
                        break;
                    }
                }
                return result;
            }

        }
        /// <summary>
        /// 判断是否有空白，并取消行数限制
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static JudgeNullModal YXHJudgeNullinCSVModal(this FileInfo fileInfo, string[] list)
        {
            JudgeNullModal modal = new JudgeNullModal();
            if (list.Length != 2561)
            {
                modal.result=$"此{fileInfo.Name}文件不是5秒CSV文件";
            }
            list[0] = list[0].Replace(" ", "");
            int index = 0;
            foreach (var item in list)
            {
                var n = item.Split(",").Any(a => string.IsNullOrWhiteSpace(a));
                if (n)
                {

                    modal.result += $"此{fileInfo.Name}文件在{index}行为空";
                    modal.isNull = true;
                    break;
                }
                index = index + 1;
            }
            return modal;
        }
        /// <summary>
        /// 一次性的保存成CSV
        /// </summary>
        /// <param name="filepath">保存路径</param>
        /// <param name="newlist">List数据</param>
        /// <returns></returns>
        public static async Task YXHSaveCSVfromListOneTimeAsync(string filepath, string[] newlist)
        {
            await File.WriteAllLinesAsync(filepath, newlist);
        }
        /// <summary>
        /// 有时候can里的车速为0，但是gps里有车速，那就用此方法把can里的车速替换为gps里的车速
        /// </summary>
        /// <param name="input"></param>
        /// <param name="index1">gps车速</param>
        /// <param name="index2">can里的车速</param>
        /// <returns></returns>
        public static string ReplaceAtIndex(string input, int index1, int index2)
        {
            // 将输入字符串按逗号分割
            string[] parts = input.Split(',');
            //两个速度的index值不同才会进行转换，如果相同则意味着你不需要转换
            if (index1 != index2 && index1<parts.Length && index2 < parts.Length &&index1>0 &&index2>0)
            {
                // 判断 index2 的数字是否为 0，因为之前已经清洗过了，所以异常的都是为0，并且 index1 的数字是否在 0 到 180 之间
                if (double.TryParse(parts[index2], out double number2) && number2 == 0
                    && double.TryParse(parts[index1], out double number1) && number1 > 0 && number1 < 200)
                {
                    // 将 index2 的数字替换为 index1 的数字
                    parts[index2] = number1.ToString();
                }
                // 将字符串列表用逗号连接成一个字符串
                string output = string.Join(",", parts);
                // 返回结果字符串
                return output;
            }
            else
            {
                return input;
            }
          
        }
        /// <summary>
        /// 清洗单个csv文件的方法，更新为无限制行数
        /// </summary>
        /// <param name="fileInfo"></param>
        /// <param name="outdirpath">输出日期文件夹路径</param>
        /// <param name="row"></param>
        /// <returns></returns>
        public static async Task<List<string>> YXHExcuteCleanSingleAsync(this FileInfo fileInfo, string outdirpath,CleanModal row)
        {
            List<string> list = new List<string>();//专用于输出程序计算过程中的错误信息
            try
            {
                string resultpath = Path.Combine(outdirpath, fileInfo.Name);
                if (fileInfo.FullName.YXHCheckFileIsUsed())
                {
                    list.Add($"{fileInfo.Name}正在被占用");
                    return list;
                }
                //如果是0KB，直接复制到输出文件夹
                if (fileInfo.Length == 0)
                {
                    fileInfo.CopyTo(resultpath, true);
                    return list;
                }
                //判断csv文件有没有2560的整数倍行，如果没有就不处理
                var result = await File.ReadAllLinesAsync(fileInfo.FullName);//读取csv数据到List<string>,每一行为一个string
                
                if (result.Length == 1)
                {
                    list.Add($"{fileInfo.Name}大小正常，但是无数据");
                    return list;
                }
                //首行去除双引号和空格,冒号
                result[0] = result[0].Replace("\"", "").Replace(" ", "");
                var re = YXHJudgeNullinCSVModal(fileInfo, result);
                if (!re.isNull)
                {

                    for (int j = 1; j < result.Length; j++)
                    {
                        //每行监测是否有冒号,有就去除
                        result[j] = result[j].Replace(":", "");
                        if (row?.errornumber.Length > 0)
                        {
                            foreach (var r in row.errornumber)
                            {
                                result[j] = Regex.Replace(result[j], @"(?<![\d.-])\" + r + @"(?![\d.-])", "0");
                            }
                        }
                        else
                        {
                            list.Add("清洗数字规则没有配置，请查看");
                            return list;
                        }
                        if (row.errornan.Length > 0)
                        {
                            foreach (var r in row.errornan)
                            {
                                //把字符串类型的规则也清零
                                result[j] = result[j].Replace(r, "0");
                            }
                        }
                        else
                        {
                            list.Add("清洗nan规则没有配置，请查看");
                            return list;
                        }
                        result[j] = Regex.Replace(result[j], ",,", ",0,");
                        result[j] = ReplaceAtIndex(result[j], row.gpsspdidx, row.canspdidx);
                        //做线性变换，如果有的话
                        if (row?.linearConvertModals?.Count > 0)
                        {

                            var values = result[j].Split(',');
                            foreach (var conversion in row.linearConvertModals)
                            {
                                int oldIndex = conversion.oldchanidx;
                                int newIndex = conversion.newchanidx;
                                double newValue = double.Parse(values[newIndex]);
                                double oldValue = newValue * conversion.k + conversion.b;
                                values[oldIndex] = oldValue.ToString();
                            }
                            result[j] = string.Join(",", values);
                        }
                    }
                    await YXHSaveCSVfromListOneTimeAsync(resultpath, result);
                }
                else
                {
                    list.Add($"{fileInfo.Name}数据{re.result}");
                }
            }
            catch (Exception ex)
            {
                list.Add($"{fileInfo.Name}文件有问题：{ex.Message}");
            }
            return list;
        }

        /// <summary>
        /// 原版单线程，（不修改OD）
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static async Task<List<string>> YXHExcuteCleanAsync(CleanModal row)
        {
            List<string> list = new List<string>();//专用于输出程序计算过程中的错误信息
            try
            {
                //先创建输出文件夹
                Directory.CreateDirectory(row.rdpath);
                //获得需要合并的源数据日期文件夹列表
                var ds = BasicFilesOperation.YXHGetProcessedDateDir(row.odpath, row.rdpath, row.datedir);
                if (ds != null)
                {
                    if (ds.Length > 0)
                    {
                        Stopwatch timer = new Stopwatch();
                        timer.Start();
                        foreach (var d in ds)
                        {
                            //先定义输出日期目录文件夹路径
                            string resultdirectorypath = Path.Combine(row.rdpath, d.Name);
                            var fileinfo = BasicFilesOperation.YXHGetAllFiles(d.FullName);
                            //如果文件夹下没有csv文件
                            if (fileinfo.Length == 0 || fileinfo == null)
                            {
                                list.Add($"{d.Name}文件夹下没有文件或文件夹路径有问题");
                            }
                            else
                            {
                                DirectoryInfo root = new DirectoryInfo(resultdirectorypath);
                                //创建日期目录文件夹
                                if (!root.Exists)
                                {
                                    root.Create();
                                }
                                //再找出所有csv文件
                                fileinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.csv");
                                if (fileinfo.Length > 0)
                                {
                                    for (int i = 0; i < fileinfo.Length; i++)
                                    {
                                        if (fileinfo[i].FullName.YXHCheckFileIsUsed())
                                        {
                                            list.Add($"{fileinfo[i].Name}正在被占用");
                                            return list;
                                        }
                                        var result = await File.ReadAllLinesAsync(fileinfo[i].FullName);//读取csv数据到List<string>,每一行为一个string
                                        if (result.Length > 0)
                                        {
                                            var re = YXHJudgeNullinCSVModal(fileinfo[i], result);
                                            if (!re.isNull)
                                            {
                                                //输出文件路径
                                                string resultpath = Path.Combine(root.FullName, fileinfo[i].Name);
                                                for (int j = 1; j < result.Length; j++)
                                                {
                                                    if (row?.errornumber.Length > 0)
                                                    {
                                                        foreach (var r in row.errornumber)
                                                        {
                                                            result[j] = Regex.Replace(result[j], @"(?<![\d.-])\" + r + @"(?![\d.-])", "0");
                                                        }
                                                    }
                                                    else
                                                    {
                                                        list.Add("清洗数字规则没有配置，请查看");
                                                        return list;
                                                    }
                                                    if (row.errornan.Length > 0)
                                                    {
                                                        foreach (var r in row.errornan)
                                                        {
                                                            //把字符串类型的规则也清零
                                                            result[j] = result[j].Replace(r, "0");
                                                        }
                                                    }
                                                    else
                                                    {
                                                        list.Add("清洗nan规则没有配置，请查看");
                                                        return list;
                                                    }
                                                    result[j] = Regex.Replace(result[j], ",,", ",0,");
                                                    result[j] = ReplaceAtIndex(result[j], row.gpsspdidx, row.canspdidx);
                                                    //做线性变换，如果有的话
                                                    if (row?.linearConvertModals?.Count > 0)
                                                    {

                                                        var values = result[j].Split(',');
                                                        foreach (var conversion in row.linearConvertModals)
                                                        {
                                                            int oldIndex = conversion.oldchanidx;
                                                            int newIndex = conversion.newchanidx;
                                                            double newValue = double.Parse(values[newIndex]);
                                                            double oldValue = newValue * conversion.k + conversion.b;
                                                            values[oldIndex] = oldValue.ToString();
                                                        }
                                                        result[j] = string.Join(",", values);
                                                    }
                                                }
                                                await YXHSaveCSVfromListOneTimeAsync(resultpath, result);
                                            }
                                            else
                                            {
                                                list.Add($"{fileinfo[i].Name}数据{re.result}");
                                            }
                                        }
                                    }
                                }
                                //筛选所有txt并复制到目标文件夹下
                                var txtinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.txt");
                                foreach (var file in txtinfo)
                                {
                                    var txtresultpath = Path.Combine(resultdirectorypath, file.Name);
                                    file.CopyTo(txtresultpath, true);
                                }
                                //获得输出文件夹里的所有数据
                                var outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                //删除相邻2个csv文件里小于5个以内的txt
                                outfileinfo.YXHDeleteTxtFiles();
                                outfileinfo = outfileinfo.Where(file => file.Extension == ".csv").ToArray();
                                //筛选0kb的csv的数据并转换成txt
                                outfileinfo.YXHTransferZeroCsvtoTxt();
                            }
                        }
                        timer.Stop();
                        list.Add($"程序总完成时间为{timer.Elapsed.TotalMinutes.ToString("0.00")}分-单线程");
                    }
                    else
                    {
                        list.Add("目标路径下已有所有数据，不进行任何操作");
                    }

                }
                else
                {
                    list.Add("目标路径有问题，请检查配置文件");
                }
            }

            catch (Exception ex)
            {
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                list.Add(methodName + "方法出现了错误：" + ex.StackTrace);
            }
            return list;
        }
        /// <summary>
        /// 清洗程序的多线程版（不修改OD），有带进度条提示，但unify的不能用这个方法
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static async Task<List<string>> YXHExcuteCleanMultiThreadAsync(CleanModal row)
        {
            List<string> list = new List<string>();//专用于输出程序计算过程中的错误信息
            try
            {
                //先创建输出文件夹
                Directory.CreateDirectory(row.rdpath);
                //获得源数据文件夹列表
                var ds = BasicFilesOperation.YXHGetProcessedDateDir(row.odpath, row.rdpath, row.datedir);
                if (ds != null)
                {
                    if (ds.Length > 0)
                    {
                        Stopwatch Btimer = new Stopwatch();
                        Btimer.Start();

                        //❤️增加的代码（显示进度）
                        var totalDirs = ds.Length;
                        int currentDirIndex = 0;

                        foreach (var d in ds)
                        {
                            //❤️增加的代码（显示进度）
                            currentDirIndex++;

                            Stopwatch Stimer = new Stopwatch();
                            Stimer.Start();
                            //先定义输出日期目录文件夹路径
                            string resultdirectorypath = Path.Combine(row.rdpath, d.Name);
                            //这里是所有的文件，包含csv和txt
                            var fileinfo = BasicFilesOperation.YXHGetAllFiles(d.FullName);
                            //如果文件夹下没有csv文件
                            if ( fileinfo == null || fileinfo.Length == 0)
                            {
                                list.Add($"{d.Name}文件夹下没有文件或文件夹路径有问题");
                            }
                            else
                            {
                                DirectoryInfo root = new DirectoryInfo(resultdirectorypath);
                                //创建日期目录文件夹
                                if (!root.Exists)
                                {
                                    root.Create();
                                }
                               
                                ////获得所有 filelist 数量大于 60 的 FileInfo 组合成的数组
                                //fileinfo =txtresult.YXHSelectMoreThan60();
                                fileinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.csv");
                                if (fileinfo.Length > 0)
                                {
                                    //文件数据集被划分成了多个子集，子集数目按照线程数量来
                                    var dividedData = fileinfo.DivideDataIntoParts(row.threadnumber);
                                    //❤️增加的代码（显示进度）
                                    int totalFiles = fileinfo.Length;
                                    int processedFiles = 0;

                                    List<Task> tasks = new List<Task>();
                                    foreach (var part in dividedData)
                                    {
                                        Task task = Task.Run(async () =>
                                        {
                                            foreach (var fileInfo in part)
                                            {
                                                var text = await fileInfo.YXHExcuteCleanSingleAsync(root.FullName, row);
                                                //List<T> 在多线程里不是线程安全的，可能会抛异常或者丢数据
                                                lock (list)
                                                {
                                                    list.AddRange(text);
                                                }
                                                //❤️增加的代码（显示进度）
                                                // 文件级进度
                                                int fileNum = Interlocked.Increment(ref processedFiles);
                                                int percent = (int)(((double)(currentDirIndex - 1) / totalDirs + (double)fileNum / totalFiles / totalDirs) * 100);
                                                ProgressReporter.Report(row.taskId, percent,
                                                    $"正在处理第 {currentDirIndex}/{totalDirs} 个文件夹，文件 {fileNum}/{totalFiles}：{fileInfo.Name}");

                                            }
                                        });
                                        tasks.Add(task);
                                    }
                                    await Task.WhenAll(tasks.ToArray());
                                }
                                //筛选所有txt并复制到目标文件夹下
                                var txtinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.txt");
                                foreach (var file in txtinfo)
                                {
                                    var txtresultpath = Path.Combine(resultdirectorypath, file.Name);
                                    file.CopyTo(txtresultpath, true);
                                }
                                //获得输出文件夹里的所有数据
                                var outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                //删除相邻2个csv文件里小于5个以内的txt
                                outfileinfo.YXHDeleteTxtFiles();
                                var outcsv = outfileinfo.Where(file => file.Extension == ".csv").ToArray();
                                //筛选0kb的csv的数据并转换成txt
                                outcsv.YXHTransferZeroCsvtoTxt();
                              //再获取所有文件
                                outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                //再按照txt分类
                                var txtresul =outfileinfo.YXHClassifyFilebyTxt();
                                //筛选出连续小于60数量的csv并删除
                                var needtodelcsv=txtresul.YXHSelectLessThan60();
                                foreach (var f in needtodelcsv)
                                {
                                    f.FullName.YXHDeleteFile();
                                }
                            }
                            Stimer.Stop();
                            list.Add($"{d.Name}清洗完成时间为{Stimer.Elapsed.TotalMinutes:0.00}分");
                        }
                        Btimer.Stop();
                        list.Add($"清洗程序总完成时间为{Btimer.Elapsed.TotalMinutes:0.00}分-多线程");
                        //❤️增加的代码（显示进度）
                        // 最终完成
                        ProgressReporter.Report(row.taskId, 100, $"清洗程序总完成时间为{Btimer.Elapsed.TotalMinutes:0.00}分-多线程",true);
                    }
                    else
                    {
                        list.Add("目标路径下已有所有数据，不进行任何操作");
                        ProgressReporter.Report(row.taskId, 101, "目标路径下已有所有数据，不进行任何操作", true);
                    }
                }
                else
                {
                    list.Add("目标路径有问题，请检查配置文件");
                    ProgressReporter.Report(row.taskId, 101, "目标路径有问题，请检查配置文件", true);
                }
            }
            catch (Exception ex)
            {
                //❤️增加的代码（显示进度）
                ProgressReporter.Report(row.taskId, 101, $"清洗失败: {ex.Message}", true);
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                list.Add(methodName + "方法出现了错误：" + ex.StackTrace);
            }
            return list;
        }

        /// <summary>
        ///  清洗程序的多线程版（不修改OD），不带进度条提示，用于unify
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static async Task<List<string>> YXHExcuteCleanMultiThreadforUnifyAsync(CleanModal row)
        {
            List<string> list = new List<string>();//专用于输出程序计算过程中的错误信息
            try
            {
                //先创建输出文件夹
                Directory.CreateDirectory(row.rdpath);
                //获得源数据文件夹列表
                var ds = BasicFilesOperation.YXHGetProcessedDateDir(row.odpath, row.rdpath, row.datedir); ;
                if (ds != null)
                {
                    if (ds.Length > 0)
                    {
                        Stopwatch Btimer = new Stopwatch();
                        Btimer.Start();

                        foreach (var d in ds)
                        {
                            Stopwatch Stimer = new Stopwatch();
                            Stimer.Start();
                            //先定义输出日期目录文件夹路径
                            string resultdirectorypath = Path.Combine(row.rdpath, d.Name);
                            //这里是所有的文件，包含csv和txt
                            var fileinfo = BasicFilesOperation.YXHGetAllFiles(d.FullName);
                            //如果文件夹下没有csv文件
                            if (fileinfo == null || fileinfo.Length == 0)
                            {
                                list.Add($"{d.Name}文件夹下没有文件或文件夹路径有问题");
                            }
                            else
                            {
                                DirectoryInfo root = new DirectoryInfo(resultdirectorypath);
                                //创建日期目录文件夹
                                if (!root.Exists)
                                {
                                    root.Create();
                                }

                                ////获得所有 filelist 数量大于 60 的 FileInfo 组合成的数组
                                //fileinfo =txtresult.YXHSelectMoreThan60();
                                fileinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.csv");
                                if (fileinfo.Length > 0)
                                {
                                    //文件数据集被划分成了多个子集，子集数目按照线程数量来
                                    var dividedData = fileinfo.DivideDataIntoParts(row.threadnumber);
                                    List<Task> tasks = new List<Task>();
                                    foreach (var part in dividedData)
                                    {
                                        Task task = Task.Run(async () =>
                                        {
                                            foreach (var fileInfo in part)
                                            {
                                                var text = await fileInfo.YXHExcuteCleanSingleAsync(root.FullName, row);
                                                //List<T> 在多线程里不是线程安全的，可能会抛异常或者丢数据
                                                lock (list)
                                                {
                                                    list.AddRange(text);
                                                }
                                            }
                                        });
                                        tasks.Add(task);
                                    }
                                    await Task.WhenAll(tasks.ToArray());
                                }
                                //筛选所有txt并复制到目标文件夹下
                                var txtinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.txt");
                                foreach (var file in txtinfo)
                                {
                                    var txtresultpath = Path.Combine(resultdirectorypath, file.Name);
                                    file.CopyTo(txtresultpath, true);
                                }
                                //获得输出文件夹里的所有数据
                                var outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                //删除相邻2个csv文件里小于5个以内的txt
                                outfileinfo.YXHDeleteTxtFiles();
                                var outcsv = outfileinfo.Where(file => file.Extension == ".csv").ToArray();
                                //筛选0kb的csv的数据并转换成txt
                                outcsv.YXHTransferZeroCsvtoTxt();
                                //再获取所有文件
                                outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                //再按照txt分类
                                var txtresul = outfileinfo.YXHClassifyFilebyTxt();
                                //筛选出连续小于60数量的csv并删除
                                var needtodelcsv = txtresul.YXHSelectLessThan60();
                                foreach (var f in needtodelcsv)
                                {
                                    f.FullName.YXHDeleteFile();
                                }
                            }
                            Stimer.Stop();
                            list.Add($"{d.Name}清洗完成时间为{Stimer.Elapsed.TotalMinutes:0.00}分");
                        }
                        Btimer.Stop();
                        list.Add($"清洗程序总完成时间为{Btimer.Elapsed.TotalMinutes:0.00}分-多线程");
                    }
                    else
                    {
                        list.Add("目标路径下已有所有数据，不进行任何操作");
                    }
                }
                else
                {
                    list.Add("目标路径有问题，请检查配置文件");
                }
            }
            catch (Exception ex)
            {
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                list.Add(methodName + "方法出现了错误：" + ex.StackTrace);
            }
            return list;
        }


        /// <summary>
        /// 清洗程序的2层多线程版,日期也多线程（不修改OD）
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static async Task<List<string>> YXHExcuteCleanMultiThread2DAsync(CleanModal row)
        {
            List<string> list = new List<string>();//专用于输出程序计算过程中的错误信息
            try
            {
                await Task.Run(() => {
                    //先创建输出文件夹
                    Directory.CreateDirectory(row.rdpath);
                    //获得需要合并的源数据日期文件夹列表
                    var ds = BasicFilesOperation.YXHGetProcessedDateDir(row.odpath, row.rdpath, row.datedir);
                    if (ds != null)
                    {
                        if (ds.Length > 0)
                        {
                            Stopwatch timer = new Stopwatch();
                            timer.Start();
                            // 使用 ParallelOptions 来指定最大并行度为 4
                            var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
                            Parallel.ForEach(ds, options, async d =>
                            {
                                // 处理每个文件夹下的文件的逻辑
                                //先定义输出日期目录文件夹路径
                                string resultdirectorypath = Path.Combine(row.rdpath, d.Name);
                                var fileinfo = BasicFilesOperation.YXHGetAllFiles(d.FullName);
                                //如果文件夹下没有csv文件
                                if (fileinfo.Length == 0 || fileinfo == null)
                                {
                                    list.Add($"{d.Name}文件夹下没有文件或文件夹路径有问题");
                                }
                                else
                                {
                                    DirectoryInfo root = new DirectoryInfo(resultdirectorypath);
                                    //创建日期目录文件夹
                                    if (!root.Exists)
                                    {
                                        root.Create();
                                    }
                                    //先找出所有csv文件
                                    fileinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.csv");
                                    if (fileinfo.Length > 0)
                                    {
                                        //文件数据集被划分成了多个子集，子集数目按照线程数量来
                                        var dividedData = fileinfo.DivideDataIntoParts(row.threadnumber);
                                        List<Task> tasks = new List<Task>();
                                        foreach (var part in dividedData)
                                        {
                                            Task task = Task.Run(async () =>
                                            {
                                                foreach (var fileInfo in part)
                                                {
                                                    var text = await fileInfo.YXHExcuteCleanSingleAsync(root.FullName, row);
                                                    list.AddRange(text);
                                                }
                                            });
                                            tasks.Add(task);
                                        }
                                        await Task.WhenAll(tasks.ToArray());
                                    }
                                    //筛选所有txt并复制到目标文件夹下
                                    var txtinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.txt");
                                    foreach (var file in txtinfo)
                                    {
                                        var txtresultpath = Path.Combine(resultdirectorypath, file.Name);
                                        file.CopyTo(txtresultpath, true);
                                    }
                                    //获得输出文件夹里的所有数据
                                    var outfileinfo = BasicFilesOperation.YXHGetAllFiles(resultdirectorypath);
                                    //删除相邻2个csv文件里小于5个以内的txt
                                    outfileinfo.YXHDeleteTxtFiles();
                                    outfileinfo = outfileinfo.Where(file => file.Extension == ".csv").ToArray();
                                    //筛选0kb的csv的数据并转换成txt
                                    outfileinfo.YXHTransferZeroCsvtoTxt();
                                }
                            });
                            timer.Stop();
                            list.Add($"程序总完成时间为{timer.Elapsed.TotalMinutes.ToString("0.00")}分");
                        }
                        else
                        {
                            list.Add("目标路径下已有所有数据，不进行任何操作");
                        }

                    }
                    else
                    {
                        list.Add("目标路径有问题，请检查配置文件");
                    }
                });
            }
            catch (Exception ex)
            {
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                list.Add(methodName + "方法出现了错误：" + ex.StackTrace);
            }
            return list;
            
        }
    }
}
